package com.zpz.framework.zpzoauth.service.impl;

import com.zpz.framework.zpzoauth.common.redis.ZpzOauthRedisService;
import com.zpz.framework.zpzoauth.common.result.ZpzOauthResultMsg;
import com.zpz.framework.zpzoauth.common.result.ZpzOauthResultStatus;
import com.zpz.framework.zpzoauth.common.utils.ZpzOauthBeanUtils;
import com.zpz.framework.zpzoauth.common.utils.ZpzOauthCommonConstant;
import com.zpz.framework.zpzoauth.common.utils.ZpzOauthRequestUtil;
import com.zpz.framework.zpzoauth.dao.*;
import com.zpz.framework.zpzoauth.pojo.pe.GetRoleMenuByRoleCodePe;
import com.zpz.framework.zpzoauth.pojo.po.*;
import com.zpz.framework.zpzoauth.pojo.qo.SaveRoleMenuQo;
import com.zpz.framework.zpzoauth.pojo.vo.GetRoleMenuVo;
import com.zpz.framework.zpzoauth.service.ZpzOauthFrameRoleMenuService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangpanzhi
 * @description 角色菜单权限关系服务实现
 * @create 2019-07-09 10:31
 */
@Configuration
@Service
public class ZpzOauthFrameRoleMenuServiceImpl implements ZpzOauthFrameRoleMenuService {
    private Logger log = LoggerFactory.getLogger(ZpzOauthFrameRoleMenuServiceImpl.class);
    @Resource
    private ZpzOauthFrameRoleMenuMapper zpzOauthFrameRoleMenuMapper;

    @Resource
    private ZpzOauthFrameRoleAccessMapper zpzOauthFrameRoleAccessMapper;


    @Resource
    private ZpzOauthFrameUserRoleMapper zpzOauthFrameUserRoleMapper;

    @Autowired
    private ZpzOauthRedisService zpzOauthRedisService;

    @Resource
    private FrameDepartmentMenuMapper frameDepartmentMenuMapper;

    @Resource
    private FrameDepartmentAccessMapper frameDepartmentAccessMapper;

    @Resource
    private FrameUserDepartmentMapper frameUserDepartmentMapper;



    public static String APPLICATION_NAME;
    @Value("${zpzOauth.redis.pre}")
    public void setApplicationName(String applicationName){
        APPLICATION_NAME=applicationName;
    }

    /**
     * 根据角色编码获取角色菜单信息集合
     *
     * @param
     * @return
     */
    @Override
    public ZpzOauthResultMsg<List<GetRoleMenuVo>> getRoleMenuListByRoleCode(HttpServletRequest request, String roleCode) throws Exception{

        List<GetRoleMenuVo> result=new ArrayList<>();
        List<GetRoleMenuByRoleCodePe> list= zpzOauthFrameRoleMenuMapper.findRoleMenuByRoleCode(roleCode);
        if (list!=null && list.size()>0){
            result= ZpzOauthBeanUtils.copyListProperties(list,GetRoleMenuVo.class);
        }
        if(result==null || result.size()<=0){
            ZpzOauthResultMsg.okForData(new ArrayList<GetRoleMenuVo>());
        }
        return ZpzOauthResultMsg.okForData(result);
    }

    /**
     * 保存角色菜单权限信息
     *
     * @param
     * @return
     */
    @Override
    public ZpzOauthResultMsg<Boolean> saveRoleMenu(HttpServletRequest request,String roleCode,String clientId, List<SaveRoleMenuQo> saveRoleMenuQoList){
        Map<String, String> license = ZpzOauthRequestUtil.getLicense(request);
        if (license==null || license.size()==0){
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10023);
        }
        String ucodeLicense = license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }
        if (StringUtils.isBlank(clientId)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.CLIENTID_NULL_31054);
        }

//        OauthClientDetails client = zpzOauthRequestUtil.getClient(clientId);
//        Integer accessType = client.getAccessType();
//        清空角色菜单信息
        FrameRoleMenu frm=new FrameRoleMenu();
        frm.setDelFlag(0);
        frm.setRoleCode(roleCode);
        List<FrameRoleMenu> listRoleMenu = zpzOauthFrameRoleMenuMapper.select(frm);
        if (listRoleMenu!=null && listRoleMenu.size()>0){
            List<Integer> ids=listRoleMenu.stream().map(FrameRoleMenu::getId).collect(Collectors.toList());
            Map mapParam = new HashMap();
            mapParam.put("frameRoleMenus",ids);
            zpzOauthFrameRoleMenuMapper.delFrameRoleMenu(mapParam);
        }

//        清空角色权限信息
        FrameRoleAccess fra=new FrameRoleAccess();
        fra.setDelFlag(0);
        fra.setRoleCode(roleCode);
        List<FrameRoleAccess> listRoleAccess=zpzOauthFrameRoleAccessMapper.select(fra);
        if (listRoleAccess!=null && listRoleAccess.size()>0){
            List<Integer> ids=listRoleAccess.stream().map(FrameRoleAccess::getId).collect(Collectors.toList());
            Map mapParam = new HashMap();
            mapParam.put("frameRoleAccesss",ids);
            zpzOauthFrameRoleAccessMapper.delFrameRoleAccess(mapParam);
        }
        //获取当前角色用户code
        FrameUserRole frameUserRole=new FrameUserRole();
        frameUserRole.setRoleCode(roleCode);
        frameUserRole.setDelFlag(0);
        List<FrameUserRole> frameUserRoleList = zpzOauthFrameUserRoleMapper.select(frameUserRole);
        if (frameUserRoleList!=null && frameUserRoleList.size()>0){
            List<String> userCodeList=frameUserRoleList.stream().map(FrameUserRole::getUserCode).collect(Collectors.toList());
            List<String> clientAccess=new ArrayList<>();
            List<String> clientInfo=new ArrayList<>();
            for(String uc : userCodeList){
                String access_token_key=APPLICATION_NAME+"_"+ ZpzOauthCommonConstant.CLIENT_INFO+":client_id:"+clientId+":user:"+uc+":access_token";
                String client_access_key=APPLICATION_NAME+"_"+"client_access:0:"+clientId+":"+uc;
                clientAccess.add(client_access_key);
                clientInfo.add(access_token_key);
            }
            //清空redis缓存
            for(String key : clientAccess){
                boolean ret_clientAccess = zpzOauthRedisService.delete(key);
                if (ret_clientAccess){
                    log.info("清空redis缓存成功（ret_clientAccess）："+key);
                }else {
                    log.info("清空redis缓存失败（ret_clientAccess）："+key);
                }
            }
            for(String key : clientInfo){
                boolean ret_clientInfo = zpzOauthRedisService.delete(key);
                if (ret_clientInfo){
                    log.info("清空redis缓存成功（ret_clientInfo）："+key);
                }else {
                    log.info("清空redis缓存失败（ret_clientInfo）："+key);
                }
            }

        }
        List<FrameRoleMenu> addList=new ArrayList<>();
        List<FrameRoleAccess> addAccessList=new ArrayList<>();
        if(saveRoleMenuQoList!=null && saveRoleMenuQoList.size()>0) {
            for (SaveRoleMenuQo obj : saveRoleMenuQoList) {
                FrameRoleMenu addObj = new FrameRoleMenu();
                addObj.setRoleCode(roleCode);
                addObj.setMenuId(obj.getMenuId());
                addObj.setCreateBy(ucodeLicense);
                addObj.setCreateDate(new Date());
                addObj.setDelFlag(0);
                addList.add(addObj);
                String[] accessList = obj.getAccessCode().split(",");
                if (accessList != null && accessList.length > 0) {
                    for (String access : accessList) {
                        if (StringUtils.isNotBlank(access)) {
                            FrameRoleAccess addAccessObj = new FrameRoleAccess();
                            addAccessObj.setRoleCode(roleCode);
                            addAccessObj.setAccessCode(access);
                            addAccessObj.setCreateBy(ucodeLicense);
                            addAccessObj.setCreateDate(new Date());
                            addAccessObj.setDelFlag(0);
                            Integer addAccessListExistCount = 0;
                            if (addAccessList != null && addAccessList.size() > 0) {
                                addAccessListExistCount = addAccessList.stream().filter((FrameRoleAccess a) -> addAccessObj.getAccessCode().equals(a.getAccessCode())).collect(Collectors.toList()).size();
                            }
                            if (addAccessListExistCount == 0) {
                                addAccessList.add(addAccessObj);
                            }
                        }
                    }
                }
            }
        }
        int retAdd = 0;
        int retAddAccess=0;
        if (addList!=null && addList.size()>0){
            retAdd = zpzOauthFrameRoleMenuMapper.insertList(addList);
        }
        if (addAccessList!=null && addAccessList.size()>0){
            retAddAccess=zpzOauthFrameRoleAccessMapper.insertList(addAccessList);
        }

        if (addList!=null && addList.size()>0 && addAccessList!=null && addAccessList.size()>0){
            if (retAdd>0 && retAddAccess>0){
                return ZpzOauthResultMsg.ok();
            }else{
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.ROLE_MENU_SAVE_FAILED_38014);
            }
        }else if ((addList!=null && addList.size()>0) || (addAccessList!=null && addAccessList.size()>0)){
            if (retAdd>0 || retAddAccess>0){
                return ZpzOauthResultMsg.ok();
            }else{
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.ROLE_MENU_SAVE_FAILED_38014);
            }
        }else{
            return ZpzOauthResultMsg.ok();
        }
    }

    @Override
    public ZpzOauthResultMsg<Boolean> saveDepartmentMenu(HttpServletRequest request, String roleCode, String clientId, List<SaveRoleMenuQo> saveRoleMenuQoList) {
        Map<String, String> license = ZpzOauthRequestUtil.getLicense(request);
        if (license==null || license.size()==0){
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10023);
        }
        String ucodeLicense = license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }
        if (StringUtils.isBlank(clientId)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.CLIENTID_NULL_31054);
        }
//        清空角色菜单信息
        FrameDepartmentMenu frm=new FrameDepartmentMenu();
        frm.setDelFlag(0);
        frm.setDepartmentId(Long.parseLong(roleCode));
        List<FrameDepartmentMenu> listRoleMenu = frameDepartmentMenuMapper.select(frm);
        if (listRoleMenu!=null && listRoleMenu.size()>0){
            List<Long> ids=listRoleMenu.stream().map(FrameDepartmentMenu::getId).collect(Collectors.toList());
            Map mapParam = new HashMap();
            mapParam.put("frameDepartmentMenus",ids);
            frameDepartmentMenuMapper.delFrameDepartmentMenu(mapParam);
        }

//        清空角色权限信息
        FrameDepartmentAccess fra=new FrameDepartmentAccess();
        fra.setDelFlag(0);
        fra.setDepartmentId(Long.parseLong(roleCode));
        List<FrameDepartmentAccess> listRoleAccess=frameDepartmentAccessMapper.select(fra);
        if (listRoleAccess!=null && listRoleAccess.size()>0){
            List<Long> ids=listRoleAccess.stream().map(FrameDepartmentAccess::getId).collect(Collectors.toList());
            Map mapParam = new HashMap();
            mapParam.put("frameDepartmentAccesss",ids);
            frameDepartmentAccessMapper.delFrameDepartmentAccess(mapParam);
        }
        //获取当前角色用户code
        FrameUserDepartment frameUserRole=new FrameUserDepartment();
        frameUserRole.setDepartmentId(Long.parseLong(roleCode));
        frameUserRole.setDelFlag(0);
        List<FrameUserDepartment> frameUserRoleList = frameUserDepartmentMapper.select(frameUserRole);
        if (frameUserRoleList!=null && frameUserRoleList.size()>0){
            List<String> userCodeList=frameUserRoleList.stream().map(FrameUserDepartment::getUserCode).collect(Collectors.toList());
            List<String> clientAccess=new ArrayList<>();
            List<String> clientInfo=new ArrayList<>();
            for(String uc : userCodeList){
                String access_token_key=APPLICATION_NAME+"_"+ ZpzOauthCommonConstant.CLIENT_INFO+":client_id:"+clientId+":user:"+uc+":access_token";
                String client_access_key=APPLICATION_NAME+"_"+"client_access:2:"+clientId+":"+uc;
                clientAccess.add(client_access_key);
                clientInfo.add(access_token_key);
            }
            //清空redis缓存
            for(String key : clientAccess){
                boolean ret_clientAccess = zpzOauthRedisService.delete(key);
//                if (ret_clientAccess){
//                    log.info("清空redis缓存成功（ret_clientAccess）："+key);
//                }else {
//                    log.info("清空redis缓存失败（ret_clientAccess）："+key);
//                }
            }
            for(String key : clientInfo){
                boolean ret_clientInfo = zpzOauthRedisService.delete(key);
//                if (ret_clientInfo){
//                    log.info("清空redis缓存成功（ret_clientInfo）："+key);
//                }else {
//                    log.info("清空redis缓存失败（ret_clientInfo）："+key);
//                }
            }

        }
        List<FrameDepartmentMenu> addList=new ArrayList<>();
        List<FrameDepartmentAccess> addAccessList=new ArrayList<>();
        if(saveRoleMenuQoList!=null && saveRoleMenuQoList.size()>0) {
            for (SaveRoleMenuQo obj : saveRoleMenuQoList) {
                FrameDepartmentMenu addObj = new FrameDepartmentMenu();
                addObj.setDepartmentId(Long.parseLong(roleCode));
                addObj.setMenuId(Long.parseLong(obj.getMenuId()));
                addObj.setCreateBy(ucodeLicense);
                addObj.setCreateDate(new Date());
                addObj.setDelFlag(0);
                addList.add(addObj);
                String[] accessList = obj.getAccessCode().split(",");
                if (accessList != null && accessList.length > 0) {
                    for (String access : accessList) {
                        if (StringUtils.isNotBlank(access)) {
                            FrameDepartmentAccess addAccessObj = new FrameDepartmentAccess();
                            addAccessObj.setDepartmentId(Long.parseLong(roleCode));
                            addAccessObj.setAccessCode(access);
                            addAccessObj.setCreateBy(ucodeLicense);
                            addAccessObj.setCreateDate(new Date());
                            addAccessObj.setDelFlag(0);
                            Integer addAccessListExistCount = 0;
                            if (addAccessList != null && addAccessList.size() > 0) {
                                addAccessListExistCount = addAccessList.stream().filter((FrameDepartmentAccess a) -> addAccessObj.getAccessCode().equals(a.getAccessCode())).collect(Collectors.toList()).size();
                            }
                            if (addAccessListExistCount == 0) {
                                addAccessList.add(addAccessObj);
                            }
                        }
                    }
                }
            }
        }
        int retAdd = 0;
        int retAddAccess=0;
        if (addList!=null && addList.size()>0){
            retAdd = frameDepartmentMenuMapper.insertList(addList);
        }
        if (addAccessList!=null && addAccessList.size()>0){
            retAddAccess=frameDepartmentAccessMapper.insertList(addAccessList);
        }

        if (addList!=null && addList.size()>0 && addAccessList!=null && addAccessList.size()>0){
            if (retAdd>0 && retAddAccess>0){
                return ZpzOauthResultMsg.ok();
            }else{
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.ROLE_MENU_SAVE_FAILED_38014);
            }
        }else if ((addList!=null && addList.size()>0) || (addAccessList!=null && addAccessList.size()>0)){
            if (retAdd>0 || retAddAccess>0){
                return ZpzOauthResultMsg.ok();
            }else{
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.ROLE_MENU_SAVE_FAILED_38014);
            }
        }else{
            return ZpzOauthResultMsg.ok();
        }
    }
}
